{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SGD training\n",
      "acc =  0.8823529411764706\n",
      "Adam training\n",
      "acc =  0.8823529411764706\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "# 准备数据\n",
    "\n",
    "\n",
    "class DiabetesDataset(Dataset):\n",
    "    def __init__(self, path):\n",
    "        xy = np.loadtxt(path, delimiter=',', dtype=np.float32)\n",
    "        self.len = xy.shape[0]\n",
    "        self.x_data = torch.from_numpy(xy[:, :-1])\n",
    "        self.y_data = torch.from_numpy(xy[:, [-1]])\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        return self.x_data[index], self.y_data[index]\n",
    "\n",
    "    def __len__(self):\n",
    "        return self.len\n",
    "\n",
    "\n",
    "my_dataset = DiabetesDataset('diabetes.csv')\n",
    "train_data = DataLoader(dataset=my_dataset, batch_size=256,\n",
    "                        shuffle=True, num_workers=0)\n",
    "\n",
    "\n",
    "# 构建模型\n",
    "class My_Model(torch.nn.Module):\n",
    "    def __init__(self):\n",
    "        super(My_Model, self).__init__()\n",
    "        self.linear1 = torch.nn.Linear(8, 64)\n",
    "        self.linear2 = torch.nn.Linear(64, 32)\n",
    "        self.linear3 = torch.nn.Linear(32, 4)\n",
    "        self.linear4 = torch.nn.Linear(4, 1)\n",
    "        self.ReLu = torch.nn.ReLU()\n",
    "        self.Sigmoid = torch.nn.Sigmoid()\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.ReLu(self.linear1(x))\n",
    "        x = self.ReLu(self.linear2(x))\n",
    "        x = self.ReLu(self.linear3(x))\n",
    "        x = self.Sigmoid(self.linear4(x))\n",
    "        return x\n",
    "\n",
    "\n",
    "model = My_Model()\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "model.to(device)\n",
    "\n",
    "# construct loss and optimizer\n",
    "criterion = torch.nn.BCELoss(reduction='sum')\n",
    "# optimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n",
    "# optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n",
    "\n",
    "\n",
    "def train():\n",
    "    for epoch in range(1000):\n",
    "        for i, (input, output) in enumerate(train_data, 0):\n",
    "            input, output = input.to(device), output.to(device)\n",
    "            y_pred = model(input)\n",
    "            loss = criterion(y_pred, output)\n",
    "            # print(\"epoch = \", epoch, \" loss = \", loss.item())\n",
    "\n",
    "            optimizer.zero_grad()\n",
    "            loss.backward()\n",
    "\n",
    "            optimizer.step()\n",
    "\n",
    "\n",
    "def test():\n",
    "    with torch.no_grad():  # 不构建计算图\n",
    "        test_xy = np.loadtxt('test.csv', delimiter=',', dtype=np.float32)\n",
    "        test_x_data = torch.from_numpy(test_xy[:, :-1])\n",
    "        test_y_data = torch.from_numpy(test_xy[:, [-1]])\n",
    "        test_x_data, test_y_data = test_x_data.to(device), test_y_data.to(device)\n",
    "        y_test = model(test_x_data)\n",
    "        y_pred_label = torch.where(\n",
    "            y_test >= 0.5, torch.tensor([1.0]), torch.tensor([0.0]))\n",
    "        acc = torch.eq(y_pred_label, test_y_data).sum().item() / \\\n",
    "            test_y_data.size(0)\n",
    "        print(\"acc = \", acc)\n",
    "\n",
    "\n",
    "if __name__ == '__main__':  # windows系统下没这句会报错\n",
    "    print(\"SGD training\")\n",
    "    optimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n",
    "    train()\n",
    "    test()\n",
    "    print(\"Adam training\")\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n",
    "    train()\n",
    "    test()\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "44143c5ac5f3ceb8e37c69c3af73325ae55d21292b2c7b54871fd886482dde4c"
  },
  "kernelspec": {
   "display_name": "Python 3.6.13 ('pytorch')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.13"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
